package common;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class UserSpaceSavingAlgorithm implements Serializable {

    private Map<String, UserTweetFrequency> topUsers;

    private List<UserTweetFrequency> usersSortedByTweetCount;

    private final int maxSpace;

    public UserSpaceSavingAlgorithm(int maxSpace) {
        this.maxSpace = maxSpace;
        topUsers = new HashMap<String, UserTweetFrequency>(maxSpace);
        usersSortedByTweetCount = new LinkedList<UserTweetFrequency>();
    }

    public void processNewTweetForUser(String user) {
        if (topUsers.containsKey(user)) {
            topUsers.get(user).incrementTweetCount();
            Collections.sort(usersSortedByTweetCount);
        } else if (topUsers.size() < maxSpace) {
            final UserTweetFrequency newWord = new UserTweetFrequency(user);
            topUsers.put(user, newWord);
            usersSortedByTweetCount.add(newWord);
            Collections.sort(usersSortedByTweetCount);
        } else {
            final UserTweetFrequency userToRemove = usersSortedByTweetCount.get(0);

            topUsers.remove(user);
            usersSortedByTweetCount.remove(0);

            final UserTweetFrequency newWord = new UserTweetFrequency(user, userToRemove.getTweetCount());
            newWord.incrementTweetCount();

            topUsers.put(user, newWord);
            usersSortedByTweetCount.add(newWord);
            Collections.sort(usersSortedByTweetCount);
        }
    }

    public List<UserTweetFrequency> getTopItems(int count) {
        final List<UserTweetFrequency> result = new ArrayList<UserTweetFrequency>();

        if (usersSortedByTweetCount.size() <= count) {
            for (final UserTweetFrequency uf : usersSortedByTweetCount) {
                result.add(new UserTweetFrequency(uf.getUser(), uf.getTweetCount()));
                Collections.reverse(result);
            }
        } else {
            for (int i = 1; i <= count; i++) {
                final UserTweetFrequency uf = usersSortedByTweetCount.get(usersSortedByTweetCount.size() - i);
                result.add(new UserTweetFrequency(uf.getUser(), uf.getTweetCount()));
            }
        }

        return result;
    }

    public void reset() {
        topUsers.clear();
        usersSortedByTweetCount.clear();
    }
}
